import json
import logging
import os

import shutil
from django.conf import settings
from django.http import HttpResponse
from django.shortcuts import render
from django.views import View
from django.views.decorators.csrf import csrf_exempt
from sorl.thumbnail import get_thumbnail

from label import utils
from label.WheelForm import WheelForm
from label.forms import UploadFileForm
from label.models import Wheel, WheelForm2, HistoryForm, History

logger = logging.getLogger('django')


def index(request):
    return render(request, 'index.html')


# 历史轮型列表
def wheel_history(request, wheel_type):
    # data = {'16': ['#1', '#2', '#3', '#4', ], '17': ['#5', '#6', '#7', '#8', ]}
    records = History.objects.all()
    wheel_size = ['16', '17', '18', '19']
    data = []
    for r in records:
        im = get_thumbnail(r.image_top, '100x100', crop='center', quality=100)
        data.append({'id': r.wheel_id, 'index': r.index, 'image_top': im.url})

    return render(request, 'history_list.html', {'wheel_type': wheel_type, 'data': json.dumps(data)})


# 更新历史操作记录
def wheel_history_update(request, wheel_id):
    if request.method == 'POST':
        status = 'failed'
        # print(request.POST)
        form = HistoryForm(request.POST)
        if form.is_valid():
            status = 'success'
            History.objects.update_or_create(index=form.cleaned_data['index'],
                                             image_top=form.cleaned_data['image_top'],
                                             wheel_id=form.cleaned_data['wheel_id'],
                                             wheel_size=form.cleaned_data['wheel_size'])

        return HttpResponse(json.dumps({'status': status}), content_type='application/json')


# 选择轮型
def wheel_list(request, wheel_id):
    wheel_size = {'1': 16, '2': 17, '3': 18, '4': 19, }
    wheel_customer = {'1': '美', '2': '韩', '3': '印', '4': '巴', }
    # 顾客格式: p11
    size = wheel_size[wheel_id[1]]
    customer = wheel_customer[wheel_id[2]]

    data = Wheel.objects.filter(customer=customer, size=size).order_by('-id')
    result = {'is_empty': True}
    if data.count() > 0:
        result = {'data': data, 'is_empty': False}
    return render(request, 'select_wheel.html', result)


# 新增轮型
def new_wheel(request):
    if request.method == 'POST':
        status = 'failed'
        # print(request.POST)
        form = WheelForm2(request.POST)
        if form.is_valid():
            status = 'success'
            form.save()

        return HttpResponse(json.dumps({'status': status}), content_type='application/json')
    else:
        form = WheelForm()
        return render(request, 'new_wheel.html', {'form': form})


# 确认画面
def wheel_confirm(request, wheel_id):
    wheel = Wheel.objects.get(id=wheel_id)
    #wheel['image_top'] += '/media'
    return render(request, 'item_confirm.html', {'wheel': wheel})


# 打印画面跳转
def wheel_print(request, wheel_id):
    pass


# 上载
# Utils
def make_response(status=200, content_type='text/plain', content=None):
    """ Construct a response to an upload request.
    Success is indicated by a status of 200 and { "success": true }
    contained in the content.

    Also, content-type is text/plain by default since IE9 and below chokes
    on application/json. For CORS environments and IE9 and below, the
    content-type needs to be text/html.
    """
    response = HttpResponse()
    response.status_code = status
    response['Content-Type'] = content_type
    response.content = content
    return response


class UploadView(View):
    """ View which will handle all upload requests sent by Fine Uploader.
    See: https://docs.djangoproject.com/en/dev/topics/security/#user-uploaded-content-security

    Handles POST and DELETE requests.
    """

    @csrf_exempt
    def dispatch(self, *args, **kwargs):
        return super(UploadView, self).dispatch(*args, **kwargs)

    def post(self, request, *args, **kwargs):
        """A POST request. Validate the form and then handle the upload
        based ont the POSTed data. Does not handle extra parameters yet.
        """
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            handle_upload(request.FILES['qqfile'], form.cleaned_data)
            return make_response(content=json.dumps({'success': True}))
        else:
            return make_response(status=400,
                                 content=json.dumps({
                                     'success': False,
                                     'error': '%s' % repr(form.errors)
                                 }))

    def delete(self, request, *args, **kwargs):
        """A DELETE request. If found, deletes a file with the corresponding
        UUID from the server's filesystem.
        """
        qquuid = kwargs.get('qquuid', '')
        if qquuid:
            try:
                handle_deleted_file(qquuid)
                return make_response(content=json.dumps({'success': True}))
            except Exception as e:
                return make_response(status=400, content=json.dumps({
                    'success': False,
                    'error': '%s' % repr(e)
                }))
        return make_response(status=404,
                             content=json.dumps({
                                 'success': False,
                                 'error': 'File not present'
                             }))


def handle_upload(f, fileattrs):
    """ Handle a chunked or non-chunked upload.
    """
    logger.info(fileattrs)

    chunked = False
    dest_folder = os.path.join(settings.UPLOAD_DIRECTORY, fileattrs['qquuid'])
    dest = os.path.join(dest_folder, fileattrs['qqfilename'])

    # Chunked
    if fileattrs.get('qqtotalparts') and int(fileattrs['qqtotalparts']) > 1:
        chunked = True
        dest_folder = os.path.join(settings.CHUNKS_DIRECTORY, fileattrs['qquuid'])
        dest = os.path.join(dest_folder, fileattrs['qqfilename'], str(fileattrs['qqpartindex']))
        logger.info('Chunked upload received')

    utils.save_upload(f, dest)
    logger.info('Upload saved: %s' % dest)

    # If the last chunk has been sent, combine the parts.
    if chunked and (fileattrs['qqtotalparts'] - 1 == fileattrs['qqpartindex']):
        logger.info('Combining chunks: %s' % os.path.dirname(dest))
        utils.combine_chunks(fileattrs['qqtotalparts'],
                             fileattrs['qqtotalfilesize'],
                             source_folder=os.path.dirname(dest),
                             dest=os.path.join(settings.UPLOAD_DIRECTORY, fileattrs['qquuid'], fileattrs['qqfilename']))
        logger.info('Combined: %s' % dest)

        shutil.rmtree(os.path.dirname(os.path.dirname(dest)))


def handle_deleted_file(uuid):
    """ Handles a filesystem delete based on UUID."""
    logger.info(uuid)

    loc = os.path.join(settings.UPLOAD_DIRECTORY, uuid)
    shutil.rmtree(loc)
